package com.iring.service.pbx.udpsocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.iring.dao.pbx.UDPTaskDao;
import com.iring.domain.common.DeviceInfo;
import com.iring.domain.config.UDPEnum;
import com.iring.domain.pbx.udprec.UDPVO;
import com.iring.service.common.DeviceService;
import com.iring.util.common.JacksonUtil;
import com.iring.util.common.StringUtil;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import io.netty.util.CharsetUtil;

/**
 * netty处理handler
 *
 * @author wanggan
 */
public class NettyUDPHandler extends SimpleChannelInboundHandler<DatagramPacket> {

    private static final Logger logger = LoggerFactory.getLogger(NettyUDPHandler.class);

    private DeviceService deviceService;

    UDPTaskDao task = new UDPTaskDao();// 查询任务列表

    public NettyUDPHandler(DeviceService deviceService) {
        this.deviceService = deviceService;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {

        String body = "";
        ByteBuf buf = packet.copy().content();
        try {
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            body = new String(req, "UTF-8");
        } finally {
            buf.release();
        }

        if(StringUtil.isEmpty(body)){
            buf.release();
            return;
        }
        //获取客户端的ip地址
        String clientip = packet.sender().getAddress().getHostAddress();
        //获取客户端的端口
        Integer clientport = packet.sender().getPort();

        UDPVO udpvo = JacksonUtil.readValue(body, UDPVO.class);
        String udpType = udpvo.getType();

        // 回复一条信息给客户端
        String res = null;
        if (UDPEnum.UDP_ALIVE.getValue().equals(udpType)) {
            // 查看msgtype是不是iringtel，如果不是，直接丢弃
            String mac = udpvo.getMac();
            DeviceInfo deviceInfo = deviceService.updateDeviceStatus(mac, clientip, clientport);
            if (null == deviceInfo) {
                return;
            }
            if (task.isHaveTask(mac)) {
                res = task.getValue(mac);
            }
        }
        if(StringUtil.isEmpty(res)){
            return;
        }
        ctx.writeAndFlush(new DatagramPacket(Unpooled.copiedBuffer(res, CharsetUtil.UTF_8),packet.sender()))
                    .sync();

    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush(); // 4 channel读取完成之后需要输出缓冲流。如果没有这一步，你会发现postman同样会一直在刷新
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.info("exceptionCaught...={}",cause);
        ctx.close();
    }
}
